package FileClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Observable;
import java.util.Observer;

import Constants.constants;
import se.lth.cs.realtime.RTThread;

/**
 * Denna klass läser hela tiden av data från en InputStream med tillhörande id,
 * efter hand sätts data samman till antingen en bild eller ett kommando som
 * skickas vidare till clienten. Anledningen till att klienten observeras är att
 * denna tråd skall stängas då anslutningen avbryts.
 */
public class ClientInput extends RTThread implements Observer {
	private InputStream is;
	private Client c;
	private String id;
	private BufferedReader br;
	private boolean connected;
	
	
	/**
	 * Konstuktor, Anmäler sig som observerare hos Client och sparar objekt referenser
	 * @param is InputStream från kameraserver
	 * @param c Klienten som data skall vidarebefodras till
	 * @param id Id för kameraserver
	 */
	public ClientInput(InputStream is, Client c, String id) {
		connected = true;
		c.addObserver(this);
		this.is = is;
		this.c = c;
		this.id = id;
		this.br=new BufferedReader(new InputStreamReader(is));
		
//		if (id.equals(Client.id1)){
//			picQ = c.getPicQueue1();
//		}else if(id.equals(Client.id2)){
//			picQ = c.getPicQueue2();
//		}else{
//		System.out.println("ERROR WHEN GETTING PICTUREQUEUE");
//		}
	}

	/**
	 * Tar emot ett kommando. Kollar om det är ett PICTURE kommando och isf tas
	 * en bild emot. Annars tar den emot ännu ett kommando. Data vidarebefodras
	 * till klienten.
	 */
	public void run() {
		while (connected) {
			byte[] commando = getBytes(4);
			if (constants.compareCommando(commando, constants.STRING)) {
				System.out.println(this.getString());
			} else {
				System.out
						.println("could not recognize command from id: " + id);
			}
		}
	}

	private String getString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Tar emot ett visst antal bytes och returnerar dem i en vektor
	 * @param nbr antal bytes
	 * @return Vektor med mottagna bytes
	 */
	private byte[] getBytes(int nbr) {
		byte[] bytes = new byte[nbr];
		int bytesRead = 0;
		int bytesLeft = bytes.length;
		int status = 0;
		while (true) {
			try {
				status = is.read(bytes, bytesRead, bytesLeft);
			} catch (IOException e) {
				break;
			}
			bytesRead += status;
			bytesLeft -= status;
			if (bytesLeft == 0) {
				break;
			}
		}
		return bytes;
	}

	/**
	 * Klienten observeras för att möjligöra disconnection
	 */
	public void update(Observable arg0, Object arg1) {
		connected = false;
	}

}
